/**
 * Copyright 2010 Jake Jackson
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jake.nb.ext.ant.completion;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JToolTip;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.StyledDocument;
import org.apache.tools.ant.module.api.support.TargetLister.Target;
import org.netbeans.api.editor.completion.Completion;
import org.netbeans.spi.editor.completion.CompletionItem;
import org.netbeans.spi.editor.completion.CompletionResultSet;
import org.netbeans.spi.editor.completion.CompletionTask;
import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
import org.netbeans.spi.editor.completion.support.CompletionUtilities;
import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities;

/**
 * The class representing the item to be displayed in the completion pop-up.
 * @author JakeJ
 */
public class AntTargetCompletionItem implements CompletionItem {

  private static final transient ImageIcon INTERNAL_ICON = new ImageIcon(
          ImageUtilities.loadImage("org/jake/nb/ext/ant/completion/resources/TargetIcon.gif")); // NOI18N
  private static final transient ImageIcon DESCRIBED_ICON = new ImageIcon(
          ImageUtilities.loadImage("org/jake/nb/ext/ant/completion/resources/EmphasizedTargetIcon.gif")); // NOI18N
  private static Color fieldColor = Color.decode("0x0000B2"); // NOI18N
  private final transient Target target;
  // insertion point of typed text... All characters between this point and "offset" will be removed
  private final transient int startOffset;
  private final transient boolean useQualifiedName;

  public AntTargetCompletionItem(final Target target, final int startOffset, final boolean useQualifiedName) {
    this.target = target;
    this.startOffset = startOffset;
    this.useQualifiedName = useQualifiedName;
  }

  public void defaultAction(final JTextComponent component) {
    final StyledDocument doc = (StyledDocument) component.getDocument();
    try {
      // clean everything between the start offSet and the next separator (" or ,)
      final String allTillEnd = doc.getText(startOffset, doc.getLength() - startOffset);

      int nextStopperIndex = startOffset;
      for (int i = 0; i < allTillEnd.length(); i++) {
        if (AntTargetCompletionProvider.STOPPER_STRINGS.contains("" + allTillEnd.charAt(i))) { // NOI18N
          nextStopperIndex = i;
          break;
        }
      }

      doc.remove(startOffset, nextStopperIndex);

      doc.insertString(startOffset, useQualifiedName ? target.getQualifiedName() : target.getName(), null);
    } catch (BadLocationException ex) {
      Exceptions.printStackTrace(ex);
    }
    //This statement will close the code completion box:
    Completion.get().hideAll();
  }

  public void processKeyEvent(final KeyEvent evt) {
  }

  public int getPreferredWidth(final Graphics graphics, final Font defaultFont) {
    return CompletionUtilities.getPreferredWidth(target.getName(), null, graphics, defaultFont);
  }

  public void render(final Graphics graphics, final Font defaultFont, final Color defaultColor, final Color backgroundColor,
                     final int width, final int height, final boolean selected) {
    final String displayName = useQualifiedName ? target.getQualifiedName() : target.getName();
    final int internalWidth = CompletionUtilities.getPreferredWidth(displayName, null, graphics, defaultFont);

    CompletionUtilities.renderHtml(target.isDescribed() ? DESCRIBED_ICON : INTERNAL_ICON, displayName, null, graphics, defaultFont,
                                   (selected ? Color.white : fieldColor), internalWidth, height, selected);
  }

  public CompletionTask createDocumentationTask() {
    return new AsyncCompletionTask(new AsyncCompletionQuery() {

      protected void query(final CompletionResultSet completionResult, final Document document, final int offset) {
        final TargetCompletionDocumentation targetCompletionDocumentation = new TargetCompletionDocumentation(target);
        if (targetCompletionDocumentation.hasDocumentation()) {
          completionResult.setDocumentation(targetCompletionDocumentation);
        }
        completionResult.finish();
      }
    });
  }

  public CompletionTask createToolTipTask() {
    return new AsyncCompletionTask(new AsyncCompletionQuery() {

      protected void query(final CompletionResultSet completionResult, final Document document, final int offset) {
        final JToolTip toolTip = new JToolTip();
        toolTip.setTipText("Press Enter to insert \"" + target.getName() + "\""); // NOI18N
        completionResult.setToolTip(toolTip);
        completionResult.finish();
      }
    });
  }

  public boolean instantSubstitution(final JTextComponent component) {
    return false;
  }

  public int getSortPriority() {
    return 0;
  }

  public CharSequence getSortText() {
    return target.getName() + "(" + target.getQualifiedName() + ")"; // NOI18N
  }

  public CharSequence getInsertPrefix() {
    return target.getName() + "(" + target.getQualifiedName() + ")"; // NOI18N
  }
}
